# ウェブアプリ用のスクリプト
# ポートフォリオの性能を計算
# コマンド引数の仕様
# [7]  計算終了日 YYYY-MM-dd のフォーマットex: 2002-01-11
# [8]  計算日数
# [9]  銘柄の個数
# [10] 0: 投資額、1: 投資比率
# [11] 銘柄コード
# ...
# [n]  投資額/比率
# ...

# 実行結果の出力
# 成功時
#	実行結果 平均 分散
# 失敗時
#	実行結果 エラーメッセージ	
# とスペース区切りで出力

library(RpgSQL)
source( "/var/www/cgi-bin/r/modules/calc_portfolio_performance.r" )

# 収益率リストを作成
create_earning_rates <- function( prices_by_code, date_interval )
{
#	print( prices_by_code )
	earning_rates_by_code <- as.list( NA )
	dates_by_code <- as.list( NA )
	index <- 1
	for ( prices in prices_by_code )
	{
		index_from <- 1
		index_to <- 2
		date_from <- as.Date( prices$date[ index_from ] )
		date_to <- as.Date( date_from ) + date_interval
		rates <- c()
		dates <- c()
#		browser()

		while ( TRUE ) 
		{
			if ( index_from > length( prices$price ) ||
				 as.numeric( date_from - date_interval ) < date_interval )
			{
				break
			}

			is_index_found <- TRUE
			while ( as.Date( prices$date[ index_to ] ) != date_to )
			{
				index_to <- index_to + 1
				if ( index_to > length( prices$date ) )
				{
					is_index_found <- FALSE
					index_to <- index_from + 1
					break
				}
			}
			if ( is_index_found )
			{
				dates[ index_from ] <- as.Date( prices$date[ index_from ] )
				rates[ index_from ] <- prices$price[ index_to ] / prices$price[ index_from ] - 1
				#break
			}

			index_from <- index_from + 1
			date_from <- prices$date[ index_from ]
			date_to <- as.Date( date_from ) + date_interval
		}
		rates <- rates[ is.na( rates ) == FALSE ]
		dates <- dates[ is.na( dates ) == FALSE ]
		earning_rates_by_code[[ index ]] <- rates
		dates_by_code[[ index ]] <- dates
		index <- index + 1
	}
	return( list( rates_by_code=earning_rates_by_code, dates_by_code=dates_by_code ) )
}

# 収益率の平均、分散リストを作成
create_earning_basic_statics_lists <- function( earning_rates_by_code, dates_by_code )
{
	code_count <- length( earning_rates_by_code )
	earning_rate_means_by_code <- c()
	earning_rate_variances_by_code <- c()
	earning_rate_covariances <- matrix( nrow=code_count, ncol=code_count )
	index <- 1
	for ( rates in earning_rates_by_code )
	{
		earning_rate_means_by_code[ index ] <- mean( rates )
		earning_rate_variances_by_code[ index ] <- var( rates )
		index <- index + 1
	}
	
	# 共分散行列を計算
	code_index <- 1
	for ( dates in dates_by_code )
	{
		code_index_2 <- 1
		for ( dates_2 in dates_by_code )
		{
			values <- c()
			values_2 <- c()
			index <- 1
			for ( date in dates )
			{
				index_2 <- 1
				for ( date_2 in dates_2 )
				{
					if ( date == date_2 )
					{
						values <- append( values, earning_rates_by_code[[ code_index ]][ index ] )
						values_2 <- append( values_2, earning_rates_by_code[[ code_index_2 ]][ index_2 ] )
					}
					index_2 <- index_2 + 1
				}
				index <- index + 1
			}
			covariance <- cov( values, values_2 )
			if ( is.na( covariance ) )
			{
				#	共分散を計算できない時は相関がないと見なす
				earning_rate_covariances[ code_index, code_index_2 ] <- 0
			}
			else
			{
				earning_rate_covariances[ code_index, code_index_2 ] <- covariance
			}
			code_index_2 <- code_index_2 + 1
		}
		code_index <- code_index + 1
	}
	return ( list( means = earning_rate_means_by_code, variances = earning_rate_variances_by_code,
		covariances=earning_rate_covariances ) )
}

process_sequence <- function()
{
	if ( length( commandArgs() ) <= 5 )
	{
		return( NULL )
	}
	
	date_count <- as.integer( commandArgs()[ 8 ] )
	end_date <- as.Date( commandArgs()[ 7 ] )
	start_date <- as.Date( commandArgs()[ 7 ] ) - date_count * 2	
	code_count <- as.integer( commandArgs()[ 8 ] )
	
	if ( is.na( date_count ) ||
	     is.na( end_date )   ||
		 is.na( start_date ) ||
		 is.na( code_count ) )
	{
		print( "ng, invalid command args" )
		return(NULL)
	}
	
	codes <- c()
	investment_rates <- c()
	for( i in 1:code_count )
	{
		codes[ i ] = commandArgs()[ i + 9 ]
		investment_rates[ i ] = commandArgs()[ i + 9 + code_count ]
	}

	# 投資額を投資比率に変換
	rate_flag = commandArgs()[ 8 ]
	if ( rate_flag != TRUE )
	{
		investment_rates <- investment_rates / sum( investment_rates )
	}

	# データベースから株価のデータを取得
	conn <- dbConnect( pgSQL( classPath='/usr/local/pgsql/share/java/jdbc4.jar' ), user='jiro', dbname='MarketDatabase' )
	prices_by_code <- as.list( NA )
	index <- 1
	for ( code in codes )
	{
		sql <- "select exchange_date as date, adjusted_end_price as price from stock_exchange_ja_table where code='"
		sql <- paste( sql, code, sep="" )
		sql <- paste( sql, "' and '", sep="" )
		sql <- paste( sql, start_date, sep="" )
		sql <- paste( sql, "' <= exchange_date and exchange_date <= '", sep="" )
		sql <- paste( sql, end_date, sep="" )
		sql <- paste( sql, "' order by exchange_date;", sep="" )
		prices_by_code[[ index ]] <- dbGetQuery( conn, sql )
		index <- index + 1
	}
	dbDisconnect( conn )

	res <- create_earnign_rates( prices_by_code, date_count )
	
	earning_rates_by_code <- res$rates
	dates_by_code <- res$dates

	res <- create_earning_basic_statics_lists( earning_rates_by_code, dates_by_code )
	earning_rate_means_by_code <- res$means
	earning_rate_variances_by_code <- res$variances
	earning_rate_covariances_by_code <- res$covariances

	res <- calc_portfolio_performance( earning_rate_means_by_code, earning_rate_variances_by_code, 
			earning_rate_covariances_by_code, investment_rates )
	
	if ( is.null( res$error_message ) == FALSE )
	{
		s <- "ng,"
		s <- paste( s, res$error_message )
		print( s )
	}
	else
	{
		s <- "ok,"
		s <- paste( s, as.string( res$mean ), sep="," )
		s <- paste( s, res$variance, sep="," )
		print ( s )
	}
}

process_sequence()
